package com.zboin.gateway.filter;

import com.zboin.common.utils.JwtUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author zhboom
 * @date 2025/7/22 22:01
 */
@Component
public class JwtAuthFilter implements GlobalFilter, Ordered {

    private final Logger logger = LoggerFactory.getLogger(JwtAuthFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        RequestPath path = exchange.getRequest().getPath();
        if (isAuthPath(path)) {
            return chain.filter(exchange);
        }

        String token = extractToken(exchange.getRequest());
        if (token == null) {
            return unauthorized(exchange, "unAuthorization request");
        }

        try {
            // 1. 校验 Token 有效性
            if (!JwtUtils.validateToken(token)) {
                return unauthorized(exchange, "invalid token");
            }

            // 2. 提取用户信息并传递给下游
            ServerHttpRequest newReq = exchange.getRequest().mutate()
                    .header("X-User-Id", JwtUtils.getUserIdFromToken(token))
                    // .header("X-User-Roles", "ROLE_USER")
                    .build();
            return chain.filter(exchange.mutate().request(newReq).build());
        } catch (Exception e) {
            logger.warn("Token verification failed: " + e.getMessage());
            return unauthorized(exchange, "Token verification failed");
        }
    }

    private boolean isAuthPath(RequestPath path) {
        return path.toString().equals("/ucenter/auth/login");
    }

    private String extractToken(ServerHttpRequest request) {
        String header = request.getHeaders().getFirst("Authorization");
        return (header != null && header.startsWith("Bearer ")) ? header.substring(7) : null;
    }

    private Mono<Void> unauthorized(ServerWebExchange exchange, String message) {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        exchange.getResponse().getHeaders().add("Content-Type", "application/json");
        String body = String.format("{\"code\":401,\"message\":\"%s\"}", message);
        return exchange.getResponse().writeWith(Mono.just(exchange.getResponse()
                .bufferFactory().wrap(body.getBytes())));
    }

    @Override
    public int getOrder() {
        return -10;
    }
}
